package com.sen.controller;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 异步Servlet示例
 * 原理：AsyncContext不是让你异步输出，而是让你同步输出，但是解放服务器端的线程使用，使用AsyncContext的时候，对于浏览器来说，他们是同步在等待输出的，
 *     但是对于服务器端来说，处理此请求的线程并没有卡在那里等待，则是把当前的处理转为线程池处理了，关键就在于线程池，
 *     服务器端会起一个线程池去服务那些需要异步处理的请求，而如果你自己每次请求去起一个线程处理的话，这就有可能会耗大量的线程。 
 * 参考：http://www.cnblogs.com/jiaoyiping/p/5979242.html
 *     http://www.tuicool.com/articles/3UreAb
 *     http://www.iteye.com/problems/101332
 *     http://www.infoq.com/cn/news/2013/11/use-asynchronous-servlet-improve
 *     http://blog.csdn.net/yangnianbing110/article/details/38090369
 */
public class TestServletAsync extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public TestServletAsync() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	    response.setContentType("text/html;charset=UTF-8");  
        PrintWriter out = response.getWriter();  
        out.println("进入Servlet的时间：" + new Date() + ".");  
        out.flush();  
	    
        request.setAttribute("org.apache.catalina.ASYNC_SUPPORTED", true);
	    //在子线程中执行业务调用，并由其负责输出响应，主线程退出  
        final AsyncContext ctx = request.startAsync();  
        ctx.setTimeout(200000);  
        new Work(ctx).start();  
        out.println("结束Servlet的时间：" + new Date() + ".");  
        out.flush();  
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
	}
	
	//异步Servlet示例(客户端浏览器同步等待)
	class Work extends Thread{  
        private AsyncContext context;  
          
        public Work(AsyncContext context){  
            this.context = context;  
        }  
        @Override  
        public void run() {  
            try {  
                Thread.sleep(2000);//让线程休眠2s钟模拟超时操作  
                PrintWriter wirter = context.getResponse().getWriter();           
                wirter.write("延迟输出");  
                wirter.flush();  
                context.complete();  
            } catch (InterruptedException e) {  
                  
            } catch (IOException e) {  
                  
            }  
        }  
    } 

}
